<!-- 基础数据详情 -->
<script setup lang="ts">
import { ref, onActivated, onMounted, computed  } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { useRoute, useRouter } from "vue-router"
import { detailStructField, saveStructField, searchStructDataApi } from "@@/apis/basic-data"
import componentVue from "./components/component.vue"
import basicDrawer from "@@/components/plugins/DrawerParamAdd.vue"
import { BasicDataInfo, BasicEnumField, BasicClassField, SaveRequestData } from "@@/apis/basic-data/types";
import { BSDataTypeEnum, RecordTypeEnum, FormTypeEnum } from "@@/constants/other-keys";
import { VxeTablePropTypes } from "vxe-table";
import { cloneDeep } from "lodash";
import { v4 as uuidv4 }  from "uuid";
import XEUtils, { isEmpty } from "xe-utils";
import "@@/components/plugins/EditDownModal"
import EnumDrawer from "./components/DrawerEnum.vue"
import { Edit } from "@element-plus/icons-vue"
import SelectTag from "@@/components/SelectTag/index.vue"
import { closeRoute } from "@/common/composables/useCloseRouteListener";
;

defineOptions({
  name: "BasicDataView"
})

const route = useRoute()
const router = useRouter()
const curId = ref<string>(route.query.id as string)
const component = ref<BasicDataInfo>({
  name: "",
  code: "",
  description: "",
  tag: "",
  type: BSDataTypeEnum.Class,
  parentId: "",
  separator: "",
  id: route.query.id as string
});
const rules = ref({
  code: [
    { required: true, message: '请输入', trigger: "blur" },
    { message: "第一个字符必须是字母（大小写均可）或下划线 _", pattern: /^[a-zA-Z_][a-zA-Z0-9_]*$/, trigger: "blur" }
  ],
  separator: [{ required: true, message: "请输入", trigger: "blur" }]
});
const activeTab = ref("table")
const tableData = ref<BasicClassField[] | BasicEnumField[]>([])
const listObj = ref({})  //列表的数据
const fieldTableRef = ref()
// 备份原始数据
const initComInfo = ref<BasicDataInfo>()
const initTableData = ref<BasicClassField[] | BasicEnumField[]>([])
// 编辑的参数
const editParamValue = ref<BasicClassField | BasicEnumField>()
const dialogType = ref<FormTypeEnum>(FormTypeEnum.CREATE)
const isEdit = ref<boolean>(false)

const DEFAULT_ITEM_VALUE: BasicClassField = {
  name: undefined,
  code: undefined,
  type: BSDataTypeEnum.Base,
  typeId: undefined,
  typeCode: undefined,
  separator: undefined,
  recordType: RecordTypeEnum.Base,
  staticFlag: 1,
  value: "",
  sort: tableData.value.length + 1
}
const DEFAULT_ENUM_VALUE: BasicEnumField = {
  value: undefined,
  code: undefined,
  common: undefined,
}
const validRules = ref<VxeTablePropTypes.EditRules>({
  code: [
    { required: true, message: '参数名不能为空', trigger: "blur" },
    { message: "第一个字符必须是字母（大小写均可）或下划线 _", pattern: /^[a-zA-Z_][a-zA-Z0-9_]*$/, trigger: "blur" }
  ],
  typeCode: [
    { required: true, message: '数据类型必选择' },
  ]
})
const validEnumRules = ref<VxeTablePropTypes.EditRules>({
  code: [{ required: true, message: '枚举值不能为空', trigger: "blur" }]
})
// 新增参数
const insertFields = ref<BasicEnumField[] | BasicClassField[]>([])
// 删除参数
const removeFields = ref<BasicEnumField[] | BasicClassField[]>([])
// 更新参数
const updateFields = ref<BasicEnumField[] | BasicClassField[]>([])

const componentRef = ref<any>(null)
// 查看参数
const detailData = ref({
  name: '',
  code: '',
  type: 'base',
  typeId: 0,
  separator: '',
  recordType: '',
  typeCode: '',
})
const parentOptions = ref<{ label: string; value: string }[]>([])

const handleTopCreateTask = () => {
  dialogType.value = FormTypeEnum.CREATE
  dialogVisible.value = true
}
const handleCreateTask = async (record?: BasicClassField | BasicEnumField) => {
  if (record == undefined) {
    if (component.value.type == BSDataTypeEnum.Class) {
      record = cloneDeep(DEFAULT_ITEM_VALUE)
    } else {
      record = cloneDeep(DEFAULT_ENUM_VALUE)
    }
  }
  record.id = uuidv4()
  record.isAdd = true
  tableData.value = getFullData()
  tableData.value.push(record)
  insertFields.value.push(record)
  fieldTableRef.value.setEditRow(record, 'code');
}
const deleteBtn = computed(() => {
  if (fieldTableRef.value) {
    const selectRecords = fieldTableRef.value.getCheckboxRecords()
    return selectRecords.length > 0
  }
  return false
})
const removeNode = (id: string) => {
  XEUtils.eachTree(tableData.value, item => {
    if (id === item.id) {
      removeFields.value.push(item)
    }
  }, { children: 'children' })
  tableData.value = tableData.value.filter(item => item.id != undefined && item.id != id)
  insertFields.value = insertFields.value.filter(item => item.id != undefined && item.id != id)
  updateFields.value = updateFields.value.filter(item => item.id != undefined && item.id != id)
}
// 批量删除参数
const handleMultipleDelete = () => {
  if (fieldTableRef.value) {
    const selectRecords = fieldTableRef.value.getCheckboxRecords()
    const ids: string[] = []
    const names: string[] = []
    selectRecords.forEach((item: { id: string; code: string; }) => {
      ids.push(item.id as string)
      names.push(item.code as string)
    })
    ElMessageBox.confirm(`正在删除参数：${names.join("，")}，确认删除？`, "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning"
    }).then(() => {
      const delIds: string[] = []
      XEUtils.eachTree(selectRecords, item => {
        if (!removeFields.value.some(obj => item.id === obj.id)) {
          delIds.push(item.id)
          removeFields.value.push(item)
        }
      }, { children: 'children' })
      insertFields.value = insertFields.value.filter(item => item.id != undefined && !delIds.includes(item.id))
      updateFields.value = updateFields.value.filter(item => item.id != undefined && !delIds.includes(item.id))
      tableData.value = getFullData().filter(item => item.id != undefined && !delIds.includes(item.id))
    })
  }
}
// 保存
const handleSave = async () => {
  if (!componentRef.value) return false
  if (!fieldTableRef.value) return false
  const valueErrors = await fieldTableRef.value.validate(true);
  if (valueErrors) {
    ElMessage.warning("参数校验未通过")
    return
  }
  return await componentRef.value.validate().then((valid) => {
    // 获取完整数据并更新顺序
    const resultTableData = getFullData();
    const sortedResultData = updateSortField(resultTableData);
    // 更新 insertFields 中的 sort 字段
    insertFields.value = insertFields.value.map(item => {
      const sortedItem = sortedResultData.find(sorted => sorted.id === item.id);
      if (sortedItem) {
        return { ...item, sort: sortedItem.sort + 1 };
      }
      return item;
    });
      // 将不在 insertFields 中的记录放入 updateFields
    updateFields.value = sortedResultData.filter(item =>
      !insertFields.value.some(insertItem => insertItem.id === item.id)
    );
    const _insertFields = cloneDeep(insertFields.value)
    _insertFields.forEach(item => {
      delete item.id
    })
    const compItem = cloneDeep(component.value)
    compItem.tag = JSON.stringify(compItem.tag)
    let saveData: SaveRequestData = {
      basicData: cloneDeep(compItem),
      insertFields: undefined,
      insertEnums: undefined,
      removeFields: undefined,
      removeEnums: undefined,
      updateFields: undefined,
      updateEnums: undefined
    }
    delete saveData.basicData.parentBasicData
    // 过滤掉 isAdd 的记录
    updateFields.value = updateFields.value.filter(item => !item.isAdd);
    removeFields.value = removeFields.value.filter(item => !item.isAdd);

    if (component.value.type == BSDataTypeEnum.Class) {
      saveData.insertFields = _insertFields as BasicClassField[];
      saveData.updateFields = updateFields.value as BasicClassField[];
      saveData.removeFields = removeFields.value as BasicClassField[];
    }
    if (component.value.type == BSDataTypeEnum.Enum) {
      saveData.insertEnums = _insertFields as BasicEnumField[];
      saveData.updateEnums = updateFields.value as BasicEnumField[];
      saveData.removeEnums = removeFields.value as BasicEnumField[];
    }

    saveStructField(saveData).then((res) => {
      ElMessage.success("保存成功")
      structDetail()
      isEdit.value = false
    }).catch(() => {
      ElMessage.error("保存失败")
    })
  })
  .catch(() => {
    return false
  })
}
// 取消
const handleCancel = () => {
  // 关闭当前tab页
  closeRoute()
  router.back()
  // router.replace({ name: 'basicDataIndex' })
}
const dialogVisible = ref<boolean>(false);

// 弹窗清空数据
const clearDialogData = () => {
  dialogVisible.value = false
  detailData.value = {
    name: '',
    code: '',
    type: 'base',
    typeId: 0,
    separator: '',
    recordType: '',
    typeCode: '',
  }
}
// 保存参数集
const handleConfirm = (formData: BasicClassField | BasicEnumField) => {
  if (formData.id == undefined) {
    // 新增
    handleCreateTask(cloneDeep(formData))
  } else {
    tableData.value.forEach(item => {
      if (item.id == formData.id) {
        fieldTableRef.value.setRow(item, formData)
        return
      }
    })
  }
  dialogVisible.value = false
}

const handleEditDialog = (data: BasicClassField | BasicEnumField) => {
  dialogType.value = FormTypeEnum.EDIT
  dialogVisible.value = true
  editParamValue.value = cloneDeep(data)
}

// Cancel save handler
function handleCancelSave() {
  fieldTableRef.value.clearData()

  initComInfo.value && (component.value = cloneDeep(initComInfo.value))
  tableData.value = cloneDeep(initTableData.value)

  insertFields.value = []
  updateFields.value = []
  removeFields.value = []

  isEdit.value = false
}

// Store initial form data when entering edit mode
function handleEdit() {
  isEdit.value = true
}

async function structDetail() {
  const { data } = await detailStructField(curId.value)
  component.value = data.basicData
  component.value.tag = isEmpty(data.basicData.tag) ? [] : JSON.parse(data.basicData.tag as string)
  initComInfo.value = cloneDeep(component.value)
  if (data.basicData.type == BSDataTypeEnum.Class) {
    tableData.value = cloneDeep(data.fields)
  }
  if (data.basicData.type == BSDataTypeEnum.Enum) {
    tableData.value = cloneDeep(data.enums)
  }
  initTableData.value = cloneDeep(tableData.value)

  handleCancelSave()
}

onMounted(async () => {
  await structDetail()
  if (component.value.type == BSDataTypeEnum.Class) {
    searchStructDataApi({
      type: BSDataTypeEnum.Class,
      code: undefined,
      size: undefined,
      current_page: undefined
    }).then(({ data }) => {
      parentOptions.value = data.rows.filter(item => item.name && item.id)
      .map((item) => ({
        label: item.name!,
        value: item.id!
      }))
    })
  }
})

// 通用函数：更新数据顺序和 sort 字段
function updateSortField(resultData: BasicClassField[] | BasicEnumField[]) {
  return resultData.map((item, index) => {
    return { ...item, sort: index + 1 }; // 直接添加 sort 字段
  });
}

const getFullData = (): BasicClassField[] | BasicEnumField[] => {
  return fieldTableRef.value.getFullData()
}

onActivated(() => {
  if (curId.value !== route.query.id) {
    isEdit.value = false
    activeTab.value = 'table'
    curId.value = route.query.id as string
    structDetail()
  }
})
</script>

<template>
  <div class="app-container pager-container">
    <div class="app-container-content">
      <div class="cpi-header">
        <span class="cpi-header-text">基本信息</span>
        <el-button @click="handleEdit" :icon="Edit" class="edit" v-if="!isEdit">
          编辑
        </el-button>
        <div v-if="isEdit">
          <el-button @click="handleCancelSave">
            取消保存
          </el-button>
          <el-button type="primary" v-throttle="() => handleSave()">
            保存
          </el-button>
        </div>
      </div>
      <div class="basic-data-create-table" v-if="isEdit">
        <el-form ref="componentRef" :model="component" status-icon :rules="rules" label-position="right" label-width="100" class="demo-component">
          <el-row :gutter="24">
            <el-col :sm="12" :lg="6">
              <el-form-item label="名称" prop="code">
                <el-input v-model="component.code" placeholder="请输入" autocomplete="off" />
              </el-form-item>
            </el-col>
            <el-col :sm="12" :lg="6">
              <el-form-item label="别名" prop="name">
                <el-input v-model="component.name" placeholder="请输入" autocomplete="off" />
              </el-form-item>
            </el-col>
            <el-col :sm="12" :lg="6" v-if="component.type == BSDataTypeEnum.Class">
              <el-form-item label="参数连接符" prop="separator">
                <el-input v-model="component.separator" placeholder="请输入" autocomplete="off" />
              </el-form-item>
            </el-col>
            <el-col :sm="12" :lg="6">
              <el-form-item label="标签" prop="tag">
                <SelectTag module="basicData" v-model:task_tags="component.tag" :max-collapse-tags="2" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="24">
            <el-col :sm="12" :lg="6" v-if="component.type == BSDataTypeEnum.Class">
              <el-form-item label="父类" prop="parentId">
                <el-select v-model="component.parentId" filterable placeholder="请选择" style="width: 100%">
                  <el-option
                    v-for="item in parentOptions"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :sm="12" :lg="12">
              <el-form-item label="描述" prop="description">
                <el-input v-model="component.description" type="textarea" show-word-limit maxlength="200" placeholder="请输入" autocomplete="off" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>

      <el-form v-else label-position="right" label-width="100">
        <el-row :gutter="24">
          <el-col :sm="12" :lg="6">
            <el-form-item label="名称：">
              <span :title=" $getViewText(component.code)">{{ $getViewText(component.code) }}</span>
            </el-form-item>
          </el-col>
          <el-col :sm="12" :lg="6">
            <el-form-item label="别名：">
              <span :title=" $getViewText(component.name)">{{ $getViewText(component.name) }}</span>
            </el-form-item>
          </el-col>
          <el-col :sm="12" :lg="6" v-if="component.type == BSDataTypeEnum.Class">
            <el-form-item label="参数连接符：">
              <span :title=" $getViewText(component.separator)">{{ $getViewText(component.separator) }}</span>
            </el-form-item>
          </el-col>
          <el-col :sm="12" :lg="6">
            <el-form-item label="标签：">
              <el-tag v-for="item in component.tag">
                {{ item }}
              </el-tag>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :sm="12" :lg="6" v-if="component.type == BSDataTypeEnum.Class">
            <el-form-item label="父类：">
              <span :title=" $getViewText(component.parentBasicData?.code)">{{ $getViewText(component.parentBasicData?.code) }}</span>
            </el-form-item>
          </el-col>
          <el-col :sm="12" :lg="12">
            <el-form-item label="描述：">
              <span :title=" $getViewText(component.description)">{{ $getViewText(component.description) }}</span>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <div class="cpi-header">
        <span class="cpi-header-text">参数集</span>
        <span class="cpi-header-text-right">
          <span class="cpi-header-text-right-text" @click="activeTab = 'table'" :class="{ active: activeTab === 'table' }">表格</span>
          <span class="cpi-header-text-right-text" @click="activeTab = 'topology'" :class="{ active: activeTab === 'topology' }">拓扑</span>
        </span>
      </div>

      <div class="cpi-content" v-show="activeTab === 'table'">
        <div class="cpi-content-toolbar mb-3" v-if="isEdit">
          <el-space>
            <el-button type="primary" @click="handleCreateTask()">新建参数</el-button>
            <el-button :disabled="!deleteBtn" type="danger" @click="handleMultipleDelete">批量删除</el-button>
          </el-space>
        </div>
        <div class="cpi-content-main" v-if="component.type === 'class'">
          <vxe-table class="cpi-table" ref="fieldTableRef" height="auto" show-overflow highlight-hover-row show-header auto-resize keep-source size="small" :row-config="{ drag: isEdit, useKey: true }" :row-drag-config="{ trigger: 'cell', showGuidesStatus: true }" :edit-rules="validRules" :data="tableData" :mouse-config="{ selected: false }"  :edit-config="{ trigger: 'click', mode: 'row', showStatus: false }" :align="'left'" header-align="left"
          >
            <vxe-table-column :visible="isEdit" type="checkbox" width="40" />
            <vxe-table-column type="seq" title="序号" align="center" header-align="center" width="60" :drag-sort="isEdit" />
            <vxe-table-column field="code" title="参数名">
              <template #default="{ row }">
                <el-input v-if="isEdit" v-model="row.code" />
                <span v-else>{{ row.code }}</span>
              </template>
            </vxe-table-column>
            <vxe-table-column field="name" title="参数描述">
              <template #default="{ row }">
                <el-input v-if="isEdit" v-model="row.name" />
                <span v-else>{{ row.name }}</span>
              </template>
            </vxe-table-column>
            <vxe-table-column field="type" title="分类" formatter="formatType" />
            <vxe-table-column field="separator" title="参数连接符" />
            <vxe-table-column v-if="isEdit" field="typeCode" title="数据类型" :cell-render="{ name: 'EditDownModal' }" />
            <vxe-table-column v-else field="typeCode" title="数据类型">
              <template #default="{ row }">
                {{ row.typeCode }}
              </template>
            </vxe-table-column>
          </vxe-table>
        </div>
        <div class="cpi-content-main" v-if="component.type === 'enum'">
          <vxe-table class="cpi-table" ref="fieldTableRef" height="auto" show-overflow highlight-hover-row show-header auto-resize keep-source size="small" :edit-rules="validEnumRules" :data="tableData" :mouse-config="{ selected: false }"  :edit-config="{ trigger: 'click', mode: 'row', showStatus: true }" :row-config="{ drag: true, useKey: true }" :row-drag-config="{ trigger: 'cell', showGuidesStatus: false }" :align="'left'" header-align="left"
          >
            <vxe-table-column :visible="isEdit" type="checkbox" width="40" />
            <vxe-table-column type="seq" title="序号" align="center" header-align="center" width="60" />
            <vxe-table-column field="value" title="枚举名称">
              <template #default="{ row }">
                <el-input v-if="isEdit" v-model="row.value" />
                <span v-else>{{ row.value }}</span>
              </template>
            </vxe-table-column>
            <vxe-table-column field="code" title="枚举值">
              <template #default="{ row }">
                <el-input v-if="isEdit" v-model="row.code" />
                <span v-else>{{ row.code }}</span>
              </template>
            </vxe-table-column>
            <vxe-table-column field="comment" title="注释">
              <template #default="{ row }">
                <el-input v-if="isEdit" v-model="row.comment" />
                <span v-else>{{ row.comment }}</span>
              </template>
            </vxe-table-column>
          </vxe-table>
        </div>
      </div>
      <div class="cpi-content" v-if="activeTab === 'topology'">
        <componentVue :isEnum="component.type == BSDataTypeEnum.Enum" :is-edit="isEdit" :handleCreateTask="handleTopCreateTask" :fatherData="tableData || []" :adminUser="component.code" :listObj="listObj" :handleRemoveNode="removeNode" :handleEdit="handleEditDialog" />
      </div>
    </div>

    <basicDrawer v-if="component.type === BSDataTypeEnum.Class" ref="basicDrawerRef" :dialog-type="dialogType" :visible="dialogVisible" :staticFlag="1" :default-info="editParamValue" @closeDialog="clearDialogData" @handleConfirm="handleConfirm" />

    <EnumDrawer v-if="component.type === BSDataTypeEnum.Enum" ref="basicDrawerRef" :dialog-type="dialogType" :visible="dialogVisible" :default-info="editParamValue" @closeDialog="clearDialogData" @handleConfirm="handleConfirm"  />

    <div class="pager-wrapper center">
      <el-button @click="handleCancel">退出</el-button>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import "@@/assets/styles/mixins.scss";

.table_toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  height: 40px;
  span {
    height: 100%;
    flex: 1;
    text-align: center;
    line-height: 40px;
  }
  .active {
    background: #71A2D6;
  }
}
.app-container-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 10px;
  @extend %scrollbar;
}
.cpi-content {
  flex: 1;
  display: flex;
  flex-direction: column;
}
</style>

